/*
    Copyright(C) 2010 Ying-Chun Liu(PaulLiu). All rights reserved.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package org.debian.paulliu.net;

import java.io.*;
import java.util.*;
import java.net.*;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.util.logging.*;
import java.lang.reflect.*;
import org.ice4j.pseudotcp.PseudoTcpSocket;
import org.apache.commons.codec.binary.Base64;

public class PseudoTcpSocket2 extends java.net.Socket {
    PseudoTcpSocket pTcpSocket;
    InetAddress remoteAddr;

    public PseudoTcpSocket2 (org.ice4j.pseudotcp.PseudoTcpSocket pTcpSocket) {
	super();
	this.pTcpSocket = pTcpSocket;
    }

    public void setInetAddress(InetAddress remoteAddr) {
	this.remoteAddr = remoteAddr;
    }

    public InetAddress getInetAddress() {
	if (this.remoteAddr != null) {
	    return this.remoteAddr;
	} else {
	    return this.pTcpSocket.getInetAddress();
	}
    }

    /* wrapper functions */
    public void bind(SocketAddress bindpoint) throws IOException {
	this.pTcpSocket.bind(bindpoint);
    }
    public void close() throws IOException {
	this.pTcpSocket.close();
    }
    public void connect(SocketAddress endpoint) throws IOException {
	this.pTcpSocket.connect(endpoint);
    }
    public void connect(SocketAddress endpoint, int timeout) throws IOException {
	this.pTcpSocket.connect(endpoint, timeout);
    }
    public java.nio.channels.SocketChannel getChannel() {
	return this.pTcpSocket.getChannel();
    }
    public InputStream getInputStream() throws IOException {
	return this.pTcpSocket.getInputStream();
    }
    public boolean getKeepALive() throws SocketException {
	return this.pTcpSocket.getKeepAlive();
    }
    public InetAddress getLocalAddress() {
	return this.pTcpSocket.getLocalAddress();
    }
    public int getLocalPort() {
	return this.pTcpSocket.getLocalPort();
    }
    public SocketAddress getLocalSocketAddress() {
	return this.pTcpSocket.getLocalSocketAddress();
    }
    public boolean getOOBInline() throws SocketException {
	return this.pTcpSocket.getOOBInline();
    }
    public OutputStream getOutputStream() throws IOException {
	return this.pTcpSocket.getOutputStream();
    }
    public int getPort() {
	return this.pTcpSocket.getPort();
    }
    public int getReceiveBufferSize() throws SocketException {
	return this.pTcpSocket.getReceiveBufferSize();
    }
    public SocketAddress getRemoteSocketAddress() {
	return this.pTcpSocket.getRemoteSocketAddress();
    }
    public boolean getReuseAddress() throws SocketException {
	return this.pTcpSocket.getReuseAddress();
    }
    public int getSendBufferSize() throws SocketException {
	return this.pTcpSocket.getSendBufferSize();
    }
    public int getSoLinger() throws SocketException {
	return this.pTcpSocket.getSoLinger();
    }
    public int getSoTimeout() throws SocketException {
	return this.pTcpSocket.getSoTimeout();
    }
    public boolean getTcpNoDelay() throws SocketException {
	return this.pTcpSocket.getTcpNoDelay();
    }
    public int getTrafficClass() throws SocketException {
	return this.pTcpSocket.getTrafficClass();
    }
    public boolean isBound() {
	return this.pTcpSocket.isBound();
    }
    public boolean isClosed() {
	return this.pTcpSocket.isClosed();
    }
    public boolean isConnected() {
	return this.pTcpSocket.isConnected();
    }
    public boolean isInputShutdown() {
	return this.pTcpSocket.isInputShutdown();
    }
    public boolean isOutputShutdown() {
	return this.pTcpSocket.isOutputShutdown();
    }
    public void sendUrgentData(int data) throws IOException {
	this.pTcpSocket.sendUrgentData(data);
    }
    public void setKeepAlive(boolean on) throws SocketException {
	this.pTcpSocket.setKeepAlive(on);
    }
    public void setOOBInline(boolean on) throws SocketException {
	this.pTcpSocket.setOOBInline(on);
    }
    public void setPerformancePreferences(int connectionTime,
					  int latency,
					  int bandwidth) {
	this.pTcpSocket.setPerformancePreferences(connectionTime, latency, bandwidth);
    }
    public void setReceiveBufferSize(int size) throws SocketException {
	this.pTcpSocket.setReceiveBufferSize(size);
    }
    public void setReuseAddress(boolean on) throws SocketException {
	this.pTcpSocket.setReuseAddress(on);
    }
    public void setSendBufferSize(int size) throws SocketException {
	this.pTcpSocket.setSendBufferSize(size);
    }
    public void setSoLinger(boolean on, int linger) throws SocketException {
	this.pTcpSocket.setSoLinger(on, linger);
    }
    public void setSoTimeout(int timeout) throws SocketException {
	this.pTcpSocket.setSoTimeout(timeout);
    }
    public void setTcpNoDelay(boolean on) throws SocketException {
	this.pTcpSocket.setTcpNoDelay(on);
    }
    public void setTrafficClass(int tc) throws SocketException {
	this.pTcpSocket.setTrafficClass(tc);
    }
    public void shutdownInput() throws IOException {
	this.pTcpSocket.shutdownInput();
    }
    public void shutdownOutput() throws IOException {
	this.pTcpSocket.shutdownOutput();
    }
    public String toString() {
	return this.pTcpSocket.toString();
    }

    public boolean equals(Object obj) {
	return this.pTcpSocket.equals(obj);
    }
    
}
